package com.umeox.watch.httpclient.core;

import com.alibaba.fastjson.JSONObject;
import com.umeox.watch.httpclient.core.constant.HttpMethod;
import com.umeox.watch.httpclient.core.constant.ParamPosition;
import com.umeox.watch.httpclient.core.constant.Scheme;
import com.umeox.watch.httpclient.core.exception.SdkException;

import java.util.HashMap;
import java.util.Map;

public class ApiRequest extends HttpMessage {
    private Scheme scheme;
    private HttpMethod method;
    private String host;
    private String path;
    private String url;
    private Map<String, String> pathParams;
    private Map<String, String> querys;
    private Map<String, Object> formParams;
    private Map<String, String> fileParams;

    public ApiRequest(HttpMethod method, String path) {
        this.pathParams = new HashMap<>();
        this.querys = new HashMap<>();
        this.formParams = new HashMap<>();
        this.method = method;
        this.path = path;
    }

    public ApiRequest(HttpMethod method, String path, byte[] body) {
        this.pathParams = new HashMap<>();
        this.querys = new HashMap<>();
        this.formParams = new HashMap<>();
        this.method = method;
        this.path = path;
        this.body = body;
    }

    public ApiRequest(JSONObject message) {
        this.pathParams = new HashMap<>();
        this.querys = new HashMap<>();
        this.formParams = new HashMap<>();
        this.parse(message);
    }

    public Scheme getScheme() {
        return this.scheme;
    }

    public void setScheme(Scheme scheme) {
        this.scheme = scheme;
    }

    public HttpMethod getMethod() {
        return this.method;
    }

    public void setMethod(HttpMethod method) {
        this.method = method;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPath() {
        return this.path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Map<String, String> getPathParams() {
        return this.pathParams;
    }

    public void setPathParams(Map<String, String> pathParams) {
        this.pathParams = pathParams;
    }

    public void addPathParam(String name, String value) {
        this.pathParams.put(name, value);
    }

    public Map<String, String> getQuerys() {
        return this.querys;
    }

    public void setQuerys(Map<String, String> querys) {
        this.querys = querys;
    }

    public void addQueryParam(String name, String value) {
        this.querys.put(name, value);
    }

    public Map<String, Object> getFormParams() {
        return this.formParams;
    }

    public void setFormParams(Map<String, Object> formParams) {
        this.formParams = formParams;
    }

    public void addFormyParam(String name, String value) {
        this.formParams.put(name, value);
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void addParam(String name, String value, ParamPosition position, boolean isRequired) {
        if (value == null) {
            if (isRequired) {
                throw new SdkException(String.format("param %s is not nullable, please check your codes", name));
            }
        } else {
            switch (position) {
                case HEAD:
                    this.addHeader(name, value);
                    return;
                case PATH:
                    addPathParam(name, value);
                    break;
                case QUERY:
                    addQueryParam(name, value);
                    break;
                case BODY:
                    addFormyParam(name, value);
                    break;
                default:
                    throw new SdkException("unknown param position: " + position);
            }
        }
    }
}
